package com.qyxx.platform.gsmng.common.web;

import java.io.InputStream;
import java.io.OutputStream;
import java.lang.management.ManagementPermission;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;

import com.qyxx.platform.common.json.JsonOutput;
import com.qyxx.platform.common.module.web.CrudActionSupport;
import com.qyxx.platform.common.module.web.Messages;
import com.qyxx.platform.common.orm.Page;
import com.qyxx.platform.common.orm.PropertyFilter;
import com.qyxx.platform.common.utils.web.ServletUtils;
import com.qyxx.platform.common.utils.web.struts2.Struts2Utils;
import com.qyxx.platform.gsmng.common.entity.ProcessDefinitionInstance;
import com.qyxx.platform.gsmng.common.entity.ProcessInfo;
import com.qyxx.platform.gsmng.common.entity.SimpleBean;
import com.qyxx.platform.gsmng.common.entity.TaskInstance;
import com.qyxx.platform.gsmng.common.entity.TaskRun;
import com.qyxx.platform.gsmng.common.service.ProcessTraceManager;
import com.qyxx.platform.sysmng.accountmng.entity.RoleJson;
import com.qyxx.platform.sysmng.accountmng.entity.User;
import com.qyxx.platform.sysmng.desktop.entity.DesktopToUser;
import com.qyxx.platform.sysmng.exception.GsException;
import com.qyxx.platform.sysmng.utils.Constants;

/**
 * 流程管理通用Action
 */

@Namespace("/gs")
@Results({
		@Result(name = CrudActionSupport.RELOAD, location = "process.action", type = "redirect"),
		@Result(name = "processList", location = "/WEB-INF/content/sys/workflow/from-list.jsp"),
		@Result(name = "processListMobile", location = "/WEB-INF/content/sys/workflow/from-list-mobile.jsp"),
		@Result(name = "view", location = "/WEB-INF/content/sys/workflow/process-trace.jsp"),
		@Result(name = "pass", location = "/WEB-INF/content/sys/workflow/pass-on.jsp"),
		@Result(name = "startProcessWin", location = "/WEB-INF/content/sys/workflow/start-process.jsp")
})
public class ProcessAction extends CrudActionSupport<ProcessInfo> {

	/**
	 * long
	 */
	private static final long serialVersionUID = -8820515796573950230L;

	private String userIds;
	private List<ProcessInfo> processInfo;
	private List<Task> tasks;
	private String taskId;
	private String processInstanceId;
	private Task task;
	private String bname;
	private Long bid;
	private String restart;	
	private List<SimpleBean> rptNameList ;
	private String userId;
	private String roles;
	private String variableName;
	private String value;
	private DesktopToUser desktopToUser;
	private Long desktopId;
	private Boolean isHistory;
	private Boolean isRuningMng;
	private String description;
	private String rptData;
	private String modify;	
	private String button;	
	private String approveTitle;	
	private String rejectTitle;	
	private String[] taskIds;//批量处理任务
	private String approveDesp;//审批备注/原因
	
	private String relevanceModule;
	
	protected String jsonSaveData;
	protected String jsonSenddata;
	
	
	public String getRelevanceModule() {
		return relevanceModule;
	}
	public void setRelevanceModule(String relevanceModule) {
		this.relevanceModule = relevanceModule;
	}
	
	
	public String getButton() {
		return button;
	}



	
	public void setButton(String button) {
		this.button = button;
	}

	
	public String getApproveTitle() {
		return approveTitle;
	}




	
	public void setApproveTitle(String approveTitle) {
		this.approveTitle = approveTitle;
	}




	
	public String getRejectTitle() {
		return rejectTitle;
	}




	
	public void setRejectTitle(String rejectTitle) {
		this.rejectTitle = rejectTitle;
	}




	public String getRptData() {
		return rptData;
	}


	
	public void setRptData(String rptData) {
		this.rptData = rptData;
	}


	public List<SimpleBean> getRptNameList() {
		return rptNameList;
	}

	
	public void setRptNameList(List<SimpleBean> rptNameList) {
		this.rptNameList = rptNameList;
	}

	public String getDescription() {
		return description;
	}
	
	public void setDescription(String description) {
		this.description = description;
	}

	public Boolean getIsRuningMng() {
		return isRuningMng;
	}

	public void setIsRuningMng(Boolean isRuningMng) {
		this.isRuningMng = isRuningMng;
	}

	public Boolean getIsHistory() {
		return isHistory;
	}

	public void setIsHistory(Boolean isHistory) {
		this.isHistory = isHistory;
	}

	public DesktopToUser getDesktopToUser() {
		return desktopToUser;
	}
	
	public void setDesktopToUser(DesktopToUser desktopToUser) {
		this.desktopToUser = desktopToUser;
	}
	



	public Long getDesktopId() {
		return desktopId;
	}


	
	public void setDesktopId(Long desktopId) {
		this.desktopId = desktopId;
	}


	public String getVariableName() {
		return variableName;
	}

	
	public void setVariableName(String variableName) {
		this.variableName = variableName;
	}

	
	public String getValue() {
		return value;
	}

	
	public void setValue(String value) {
		this.value = value;
	}




	public String getRoles() {
		return roles;
	}


	
	public void setRoles(String roles) {
		this.roles = roles;
	}


	public String getUserId() {
		return userId;
	}

	
	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getRestart() {
		return restart;
	}
	
	public void setRestart(String restart) {
		this.restart = restart;
	}

	public String getModify() {
		return modify;
	}

	public void setModify(String modify) {
		this.modify = modify;
	}
	
	/**
	 * @return taskIds
	 */
	public String[] getTaskIds() {
		return taskIds;
	}

	/**
	 * @param taskIds
	 */
	public void setTaskIds(String[] taskIds) {
		this.taskIds = taskIds;
	}
	
	/**
	 * @return approveDesp
	 */
	public String getApproveDesp() {
		return approveDesp;
	}
	
	/**
	 * @param approveDesp
	 */
	public void setApproveDesp(String approveDesp) {
		this.approveDesp = approveDesp;
	}

	private ProcessTraceManager processTraceManager;
	private String resourceType;
	/* 实体名（模块名.实体对象名） */
	protected String entityName;
	
	/* 模块名 */
	protected String moduleName;

	/**
	 * @return processTraceManager
	 */
	public ProcessTraceManager getProcessTraceManager() {
		return processTraceManager;
	}
	
	/**
	 * @param processTraceManager
	 */
	@Autowired
	public void setProcessTraceManager(
			ProcessTraceManager processTraceManager) {
		this.processTraceManager = processTraceManager;
	}
	
	/**
	 * @return resourceType
	 */
	public String getResourceType() {
		return resourceType;
	}

	
	/**
	 * @param resourceType
	 */
	public void setResourceType(String resourceType) {
		this.resourceType = resourceType;
	}
	
	

	
	/**
	 * @return entityName
	 */
	public String getEntityName() {
		return entityName;
	}

	
	/**
	 * @param entityName
	 */
	public void setEntityName(String entityName) {
		this.entityName = entityName;
		//解析为模块名与实体对象名
		if(StringUtils.isNotBlank(entityName)) {
			String[] astr = StringUtils.split(StringUtils.lowerCase(entityName), ".");
			if(astr.length >= 1) {
				this.moduleName = astr[0];
			} else {
				throw new GsException("请求参数错误，请检查");
			}
		} else {
			throw new GsException("请求参数错误，请检查");
		}
	}
	
	/**
	 * 修正entityName
	 * 
	 * @return
	 * @throws Exception
	 */
	private void changeEntityName() {
		if(StringUtils.isNotBlank(relevanceModule)) {
			entityName = relevanceModule.split("\\.")[1].toLowerCase() + com.qyxx.platform.gsc.utils.Constants.NAME_SPLIT_SYMBOL + entityName.split("\\.")[1];
		}
	}

	
	/**
	 * @return moduleName
	 */
	public String getModuleName() {
		return moduleName;
	}

	
	/**
	 * @param moduleName
	 */
	public void setModuleName(String moduleName) {
		this.moduleName = moduleName;
	}

	public Task getTask() {
		return task;
	}

	
	public void setTask(Task task) {
		this.task = task;
	}

	public List<Task> getTasks() {
		return tasks;
	}

	public void setTasks(List<Task> tasks) {
		this.tasks = tasks;
	}

	public String getBname() {
		return bname;
	}

	
	public void setBname(String bname) {
		this.bname = bname;
	}

	public Long getBid() {
		return bid;
	}

	public void setBid(Long bid) {
		this.bid = bid;
	}

	public String getProcessInstanceId() {
		return processInstanceId;
	}

	public void setProcessInstanceId(String processInstanceId) {
		this.processInstanceId = processInstanceId;
	}

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public List<ProcessInfo> getProcessInfo() {
		return processInfo;
	}

	public void setProcessInfo(List<ProcessInfo> processInfo) {
		this.processInfo = processInfo;
	}

	public String getUserIds() {
		return userIds;
	}

	public void setUserIds(String userIds) {
		this.userIds = userIds;
	}

	/**
	 * @return jsonSaveData
	 */
	public String getJsonSaveData() {
		return jsonSaveData;
	}
	
	/**
	 * @param jsonSaveData
	 */
	public void setJsonSaveData(String jsonSaveData) {
		this.jsonSaveData = jsonSaveData;
	}
	
	/**
	 * @return jsonSenddata
	 */
	public String getJsonSenddata() {
		return jsonSenddata;
	}
	
	/**
	 * @param jsonSenddata
	 */
	public void setJsonSenddata(String jsonSenddata) {
		this.jsonSenddata = jsonSenddata;
	}
	public void prepareStart() throws Exception {
		entity = new ProcessInfo();
	}
	/**
	 * 流程启动方法
	 * 
	 */
	@JsonOutput
	public String start() throws Exception {
		User user = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		try {
			Map<String, Object> variables = new HashMap<String, Object>();
			setEntityName(entity.getBusinessName());
			//加入审批备注
			if(StringUtils.isNotBlank(approveDesp)) variables.put(ProcessTraceManager.APPROVE_DESP, approveDesp);
			processTraceManager.startWorkflow(entity, variables,userIds,user,moduleName);
			formatMessage.setMsg(true);
		} catch (ActivitiException e) {
			if (e.getMessage().indexOf(
					"no processes deployed with key") != -1) {
				logger.warn("没有部署流程!", e);
				formatMessage.setMsg("启动流程失败：对应流程不存在");
//				formatMessage.setFlag(Messages.FAIL);
//				throw new ServiceException(
//						"没有部署流程，请在[工作流]->[流程管理]页面点击<重新部署流程>",
//						new Exception(
//								"没有部署流程，请在[工作流]->[流程管理]页面点击<重新部署流程>"));
			} else {
				formatMessage.setMsg("启动流程异常："+e.getMessage());
				formatMessage.setFlag(Messages.FAIL);
				logger.error("启动流程失败：", e);
			}
		} catch (Exception e) {
			formatMessage.setMsg("启动流程异常："+e.getMessage());
			formatMessage.setFlag(Messages.FAIL);
			logger.error("启动流程失败：", e);
		}
		Struts2Utils.renderJson(formatMessage);
		return null;
	}

	/**
	 * 桌面中的待办事宜列表
	 * 
	 * @param
	 */
	@JsonOutput
	@Override
	public String list() throws Exception {
		User user = (User) Struts2Utils
				.getSessionAttribute(Constants.USER_SESSION_ID);
		String userName = user.getLoginName();
		Long userId = user.getId();
		desktopToUser = processTraceManager.findTasks(desktopId,userId,userName);
		formatMessage.setMsg(desktopToUser);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 消息窗口中的待办事宜列表
	 */
	@JsonOutput
	public String toDoList() throws Exception {
		User user = (User) Struts2Utils
				.getSessionAttribute(Constants.USER_SESSION_ID);
		String userName = user.getLoginName();	
		Page<Map<String, Object>> page = new Page<Map<String, Object>>();
		page.setPageSize(pager.getPageSize());
		page.setPageNo(pager.getPageNo());
		page.setOrder(pager.getOrder());
		page.setOrderBy(pager.getOrderBy());
		page = processTraceManager.findAllTasks(page,userName);
		Struts2Utils.renderJson(page);
		return null;
	}
	/**
	 * 手机端的待办事宜列表
	 */
	@JsonOutput
	public String toDoListMobile() throws Exception {
		User user = (User) Struts2Utils
				.getSessionAttribute(Constants.USER_SESSION_ID);
		String userName = user.getLoginName();	
		Page<Map<String, Object>> page = new Page<Map<String, Object>>();
		page.setPageSize(pager.getPageSize());
		page.setPageNo(pager.getPageNo());
		page.setOrder(pager.getOrder());
		page.setOrderBy(pager.getOrderBy());
		page = processTraceManager.findAllTasks(page,userName);
		formatMessage.setMsg(page.getResult());
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	/**
	 * 统计待办事件数量
	 */
	@JsonOutput
	public String toDoNumber() throws Exception {
		User user = (User) Struts2Utils
				.getSessionAttribute(Constants.USER_SESSION_ID);
		String userName = user.getLoginName();	
		Page<Map<String, Object>> page = new Page<Map<String, Object>>(10);
		long number = processTraceManager.findTasksNum(page,userName);
		formatMessage.setMsg(number);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	public void prepareStartPrepare() throws Exception {
		entity = new ProcessInfo();
	} 

	/**
	 * 准备启动流程跳转页面
	 */
	@JsonOutput
	public String startPrepare() throws Exception {
		setEntityName(bname);
		entity.setBusinessId(bid);
		entity.setBusinessName(bname);
		String businessKey = entity.setBusinessKey(bname, bid);
		User user = (User) Struts2Utils
				.getSessionAttribute(Constants.USER_SESSION_ID);
		String roles = processTraceManager.getNextRoles(
				processInstanceId, moduleName, variableName, value,
				businessKey, taskId);
		if (StringUtils.isNotBlank(roles)) {// 通过角色名查询相关用户
			List<User> userList = processTraceManager
					.getUserList(roles,user, bid, processInstanceId);
			if (userList.size() == 1) {// 1.如果只有一个用户直接启动流程，
				userIds = userList.get(0).getLoginName();
				try {
					Map<String, Object> variables = new HashMap<String, Object>();
					//加入审批备注
					if(StringUtils.isNotBlank(approveDesp)) variables.put(ProcessTraceManager.APPROVE_DESP, approveDesp);
					processTraceManager.startWorkflow(entity,
							variables, userIds, user, moduleName);
				} catch (ActivitiException e) {
					if (e.getMessage().indexOf(
							"no processes deployed with key") != -1) {
						logger.warn("没有部署流程!", e);
						formatMessage.setMsg("启动流程失败：对应流程不存在");
						formatMessage.setFlag(Messages.FAIL);
					} else {
						formatMessage.setMsg("启动流程异常："
								+ e.getMessage());
						formatMessage.setFlag(Messages.FAIL);
						logger.error("启动流程失败：", e);
					}
				} catch (Exception e) {
					formatMessage.setMsg("启动流程异常：" + e.getMessage());
					formatMessage.setFlag(Messages.FAIL);
					logger.error("启动流程失败：", e);
				}
				formatMessage.setMsg(null);
				Struts2Utils.renderJson(formatMessage);
				return null;
			} else if(userList.size() > 1) {// 2.如果是多个用户再跳转到选择审批人页面
				formatMessage.setMsg(roles);
				Struts2Utils.renderJson(formatMessage);
			} else { //无人
				formatMessage.setMsg("下一环节["+roles+"]角色中没有设置用户");
				formatMessage.setFlag(Messages.FAIL);
				Struts2Utils.renderJson(formatMessage);
			}
		} else {// 角色名为空，说明是数据流启动
			try {
				Map<String, Object> variables = new HashMap<String, Object>();
				//加入审批备注
				if(StringUtils.isNotBlank(approveDesp)) variables.put(ProcessTraceManager.APPROVE_DESP, approveDesp);
				processTraceManager.startWorkflow(entity, variables,
						userIds, user, moduleName);
				formatMessage.setMsg(null);
			} catch (ActivitiException e) {
				if (e.getMessage().indexOf(
						"no processes deployed with key") != -1) {
					logger.warn("没有部署流程!", e);
					formatMessage.setMsg("启动流程失败：对应流程不存在");
					formatMessage.setFlag(Messages.FAIL);
				} else {
					formatMessage.setMsg("启动流程异常：" + e.getMessage());
					formatMessage.setFlag(Messages.FAIL);
					logger.error("启动流程失败：", e);
				}
			} catch (Exception e) {
				formatMessage.setMsg("启动流程异常：" + e.getMessage());
				formatMessage.setFlag(Messages.FAIL);
				logger.error("启动流程失败：", e);
			}
			Struts2Utils.renderJson(formatMessage);
			return null;
		}
		return null;
	}

	public void prepareGetProcess() throws Exception {
		entity = new ProcessInfo();
	}
	/**
	 * 签收并办理读取合同，跳转页面
	 * 
	 */
	public String getProcess() throws Exception {
		signFor();
		return "processList";
	}
	
	public void prepareGetProcessMobile() throws Exception {
		entity = new ProcessInfo();
	}
	
	/**
	 * 手机端签收并办理读取合同，返回json数据格式
	 * 
	 */
	@JsonOutput
	public String getProcessMobile() throws Exception {
		Map<String,Object> result = signFor();
		formatMessage.setMsg(result);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 签收任务，做数据预处理
	 */
	private Map<String, Object> signFor() {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		if (StringUtils.isNotBlank(taskId)) {
			User user = (User) Struts2Utils
			.getSessionAttribute(Constants.USER_SESSION_ID);
			task = processTraceManager.signFor(taskId, user);
			/*task = processTraceManager.getTaskById(taskId);
			String name = task.getAssignee();
			if (StringUtils.isBlank(name)) {
				// 签收
				String userName = user.getLoginName();
				processTraceManager.signFor(taskId, userName);
			}*/
			// 办理
			String bKey = processTraceManager.getBusinessKey(task
					.getProcessInstanceId());
			String a[] = entity.splitBusinessKey(bKey);
			bname = a[0];
			bid = Long.valueOf(a[1]);
			Map<String,Object> mark = processTraceManager.getFormData(taskId);//读取task中FormProperties属性值
			if(mark.size()>0){
				for(Map.Entry<String, Object> en : mark.entrySet()) {//******遍历Map集合******
					String key =en.getKey();
					Object val =en.getValue();
					if(key.equals("again")){
						restart = "1";
					}else if(key.equals("roles")){
						roles = String.valueOf(val);
					}else if(key.equals("modify")){
						modify = (String) val;
					}else if(key.equals("button")){
						button = (String) val;
					}else if(key.equals("approve_title")){
						approveTitle = (String) val;
					}else if(key.equals("reject_title")){
						rejectTitle = (String) val;
					}else if(key.equals("rpt")){
						rptNameList = new ArrayList<SimpleBean>();
						String []rpt = String.valueOf(val).split(",");
							for(String r :rpt){
								String[] rr = r.split("\\|");
								SimpleBean rptJson = new SimpleBean();
								rptJson.setKey(rr[0]);
								rptJson.setValue(rr[1]);
								rptNameList.add(rptJson);
						}
					}else {
						resultMap.put(key, val);
					}
				}
			}
			
			description = task.getDescription();
			isRuningMng = false;
			isHistory = false;
			Struts2Utils.getRequest().setAttribute("processInstanceId", task.getProcessInstanceId());
			
			resultMap.put("taskId", taskId);
			resultMap.put("bname", bname);
			resultMap.put("bid", bid);
			resultMap.put("restart", restart);
			resultMap.put("roles", roles);
			resultMap.put("modify", modify);
			resultMap.put("button", button);
			resultMap.put("approveTitle", approveTitle);
			resultMap.put("rejectTitle", rejectTitle);
			resultMap.put("rptNameList", rptNameList);
			resultMap.put("description", description);
			resultMap.put("processInstanceId", task.getProcessInstanceId());
			resultMap.put("taskName", task.getName());
			resultMap.put("executionId", task.getExecutionId());
			
			approveDesp = (String)processTraceManager.getVariable(task.getProcessInstanceId(), ProcessTraceManager.APPROVE_DESP);
			resultMap.put("approveDesp", approveDesp);
			
		} else {//是否是查询历史或则运行管理
			String bKey = processTraceManager.getBusinessKey(processInstanceId);
			String a[] = entity.splitBusinessKey(bKey);
			bname = a[0];
			bid = Long.valueOf(a[1]);	
			rptNameList = new ArrayList<SimpleBean>();
			if (StringUtils.isNotBlank(rptData)) {
			String []rpt = rptData.split(",");
				for(String r :rpt){
					String[] rr = r.split("\\|");
					SimpleBean rptJson = new SimpleBean();
					rptJson.setKey(rr[0]);
					rptJson.setValue(rr[1]);
					rptNameList.add(rptJson);
				}
			}
			isHistory = true;
			
			resultMap.put("taskId", taskId);
			resultMap.put("bname", bname);
			resultMap.put("bid", bid);
			resultMap.put("rptNameList", rptNameList);
			
		}
		return resultMap;
	}
	
	/**
	 * 获取流程中的BusinessKey
	 */
	public String getProcessBusinessKey() throws Exception {
		String bKey = processTraceManager.getBusinessKey(processInstanceId);
		formatMessage.setMsg(bKey);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	
	/**
	 * 获取流程流转信息列表
	 * 
	 */
	@JsonOutput
	public String getProcessInfoList() throws Exception {
		List<PropertyFilter> filters = PropertyFilter
		.buildFromHttpRequest(Struts2Utils.getRequest());
		PropertyFilter propertyFilterParentOrg = new PropertyFilter(
			"EQS_processInstanceId",processInstanceId);
		filters.add(propertyFilterParentOrg);
		pager = processTraceManager.searchProcess(pager, filters);
		Struts2Utils.renderJson(pager);
		return null;
	}
	
	/**
	 * 根据实体ID获取流程流转信息列表
	 * 
	 */
	@JsonOutput
	public String getProcessInfoListById() throws Exception {
		List<PropertyFilter> filters = PropertyFilter
		.buildFromHttpRequest(Struts2Utils.getRequest());
		PropertyFilter pf = new PropertyFilter(
			"EQL_businessId",String.valueOf(id));
		filters.add(pf);
		pf = new PropertyFilter(
				"EQS_businessName",entityName);
		filters.add(pf);
		pager = processTraceManager.searchProcess(pager, filters);
		Struts2Utils.renderJson(pager);
		return null;
	}

	public void prepareComplete() throws Exception {
		entity = new ProcessInfo();
	}

	/**
	 * 完成任务
	 * 
	 * @param id
	 * @return
	 */
	@JsonOutput
	public String complete() throws Exception {
		User user = (User) Struts2Utils
		.getSessionAttribute(Constants.USER_SESSION_ID);
		Map<String, Object> map = ServletUtils.getParametersStartingWith(Struts2Utils.getRequest(), "activiti_");
		processTraceManager.completeTask(entity,map,user,userIds);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}

	/**
	 * 根据自定义角色展示对应用户
	 */
	@JsonOutput
	public String getRolesList() throws Exception {
		List<RoleJson> list = null;
		User currentUser = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		if (StringUtils.isNotBlank(roles)) {
			list = processTraceManager.getUserTree(roles,currentUser,bid, processInstanceId);// 流程启动前获取用户列表
		} else {// 流程过程中获取用户列表
			String roles =processTraceManager.getNextRoles(
					processInstanceId, moduleName, variableName,
					value,"",taskId);
			if (StringUtils.isNotBlank(roles)) {
				List<User> userList = processTraceManager.getUserList(roles, currentUser, bid, processInstanceId);
				if (userList.size() == 1) {
					String uId = userList.get(0).getLoginName();
					formatMessage.setMsg(uId);
					Struts2Utils.renderJson(formatMessage);
					return null;
				}else if (userList.size() > 1){
					list = processTraceManager.getUserTree(roles,currentUser, bid, processInstanceId); 
				}else{
					formatMessage.setMsg("下一环节["+roles+"]角色中没有设置用户");
					formatMessage.setFlag(Messages.FAIL);
					Struts2Utils.renderJson(formatMessage);
					return null;
				}		
			}
		}
		
		formatMessage.setMsg(list);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	/**
	 * 取消审批
	 */
	@JsonOutput
	public String cancelModels() throws Exception {
		setEntityName(entityName);
		processTraceManager.deleteProcessInstance(id,entityName);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	/**
	 * 恢复已审批记录的流程
	 */
	@JsonOutput
	public String cancelProcess() throws Exception {	
		setEntityName(entityName);
		processTraceManager.recoverProcess(id,entityName);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	/**
	 * 作废流程过程中相应的下推单据	
	 */
	@JsonOutput
	public String recoverProcess() throws Exception {	
		setEntityName(entityName);
		processTraceManager.deleteProcessModel(id,entityName);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 作废当前单据，及流程过程中相应的下推单据	
	 */
	@JsonOutput
	public String invalidProcess() throws Exception {	
		setEntityName(entityName);
		User user = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		processTraceManager.setUser(user);
		processTraceManager.invalidProcess(id, entityName, description);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	@Override
	public String input() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String save() throws Exception {
		return null;
	}

	/**
	 * 进入流程跟踪页面
	 * @see com.qyxx.platform.common.module.web.CrudActionSupport#view()
	 */
	@Override
	public String view() throws Exception {
		return VIEW;
	}

	@Override
	public String delete() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void prepareModel() throws Exception {
		// TODO Auto-generated method stub

	}
	
	/**
	 * 加载流程资源，包括xml或图片
	 * 
	 * @return
	 * @throws Exception
	 */
	public String loadProcessDefinition() throws Exception {
		InputStream resourceAsStream = processTraceManager.loadProcess(processInstanceId, moduleName, resourceType);
		HttpServletResponse response = Struts2Utils.getResponse();
		OutputStream os = response.getOutputStream();
		byte[] b = new byte[1024];
		int len = -1;
		while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
			os.write(b, 0, len);
		}
		return null;
	}
	
	/**
	 * 加载流程活动环节执行详情，进行跟踪
	 * 
	 * @return
	 * @throws Exception
	 */
	@JsonOutput
	public String traceProcess() throws Exception {
		List<Map<String, Object>> list = processTraceManager.traceProcess(processInstanceId);
		formatMessage.setMsg(list);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	

	public String passOn() throws Exception {
		return "pass";
	}
	/**
	 * 填写待办原因描述
	 * 
	 */
	public String setTaskDescription() throws Exception {
		
		processTraceManager.setTaskDescription(taskId,description);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	/**
	 * 任务转派
	 * 
	 */
	public String delegateUser() throws Exception {
		User user = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		processTraceManager.delegateUser(taskId,userId, user);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	/**
	 * 设置下一个环节的下推数据选人
	 * 
	 */
	public String setDataUser() throws Exception {	
		processTraceManager.setFormUser(taskId,userId);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 挂起流程实例
	 * 
	 */
	public String suspendProcess() throws Exception {	
		processTraceManager.suspendProcessInst(processInstanceId);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	/**
	 * 激活流程实例
	 * 
	 */
	public String activateProcess() throws Exception {	
		processTraceManager.activateProcessInst(processInstanceId);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 获取流程办理历史
	 * 
	 */
	@JsonOutput
	public String processHistory() throws Exception {
		User user = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		Page<TaskInstance> page = new Page<TaskInstance>();
		page.setPageSize(pager.getPageSize());
		page.setPageNo(pager.getPageNo());
		page.setOrder(pager.getOrder());
		page.setOrderBy(pager.getOrderBy());
		List<PropertyFilter> filters = PropertyFilter.buildFromHttpRequest(Struts2Utils.getRequest());
			page = processTraceManager.searchProcessHistory(page,user.getLoginName(),filters);
			Struts2Utils.renderJson(page);
			return null;
	}
	/**
	 * 获取流程定义
	 * 
	 */
	@JsonOutput
	public String processInstanceHistory() throws Exception {
		Page<ProcessDefinitionInstance> page = new Page<ProcessDefinitionInstance>();
		page.setPageSize(pager.getPageSize());
		page.setPageNo(pager.getPageNo());
		page.setOrder(pager.getOrder());
		page.setOrderBy(pager.getOrderBy());
		List<PropertyFilter> filters = PropertyFilter.buildFromHttpRequest(Struts2Utils.getRequest());
			page = processTraceManager.searchProcessDefinitionHistory(page,filters);
			Struts2Utils.renderJson(page);
			return null;
			
	}
	/**
	 * 查询所有运行的流程实例
	 * 
	 */
	@JsonOutput
	public String getAllProcessInstance() throws Exception {
		Page<TaskRun> page = new Page<TaskRun>();
		page.setPageSize(pager.getPageSize());
		page.setPageNo(pager.getPageNo());
		page.setOrder(pager.getOrder());
		page.setOrderBy(pager.getOrderBy());
		List<PropertyFilter> filters = PropertyFilter.buildFromHttpRequest(Struts2Utils.getRequest());
			page =processTraceManager.searchProcessInstance(page,filters);
			Struts2Utils.renderJson(page);
			return null;
			
	}

	/**
	 * 结束运行中的流程实例
	 * 
	 */
	public String endProcessInstance() throws Exception {	
		processTraceManager.endProcess(processInstanceId);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	public  String init()throws Exception {
		return "startProcessWin";
	}
	
	/**
	 * 审核通过单据
	 */
	@JsonOutput
	public String startApprove() throws Exception {	
		setEntityName(entityName);
		changeEntityName();
		User user = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		processTraceManager.setUser(user);
		processTraceManager.startApprove(ids, entityName);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 取消审核单据
	 */
	@JsonOutput
	public String cancelApprove() throws Exception {	
		setEntityName(entityName);
		changeEntityName();
		User user = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		processTraceManager.setUser(user);
		processTraceManager.cancelApprove(ids, entityName);
		formatMessage.setMsg(true);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 批量启动流程
	 */
	@JsonOutput
	public String batchStartProcess() throws Exception {
		User currentUser = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		formatMessage.setMsg(null);
		if(StringUtils.isNotBlank(userIds)) { //存在选择用户情况下，直接同意即可
			processTraceManager.batchStartProcess(ids, entityName, userIds, currentUser);
		} else {
			id = ids[0];
			ProcessInfo pi = new ProcessInfo();
			String businessKey = pi.setBusinessKey(entityName, id);
			String roles = processTraceManager.getNextRoles(
					null, moduleName, null,
					null, businessKey, null);
			if (StringUtils.isNotBlank(roles)) {
				List<User> userList = processTraceManager.getUserList(roles, currentUser, id, null);
				if (userList.size() == 1) {
					String uId = userList.get(0).getLoginName();
					processTraceManager.batchStartProcess(ids, entityName, uId, currentUser);
				}else if (userList.size() > 1){
					formatMessage.setMsg(roles);
				}else{
					formatMessage.setMsg("下一环节["+roles+"]角色中没有设置用户");
					formatMessage.setFlag(Messages.FAIL);
				}		
			} else {
				processTraceManager.batchStartProcess(ids, entityName, "", currentUser);
			}
		}
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 批量同意单据
	 */
	@JsonOutput
	public String batchAgree() throws Exception {
		User currentUser = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		formatMessage.setMsg(null);
		if(StringUtils.isNotBlank(userIds)) { //存在选择用户情况下，直接同意即可
			processTraceManager.batchAgree(taskIds, userIds, currentUser, variableName);
		} else {
			taskId = taskIds[0];
			Task tk = processTraceManager.getTaskById(taskId);
			String pdk = tk.getProcessDefinitionId();
			moduleName = StringUtils.split(pdk, ":")[0];
			String roles = processTraceManager.getNextRoles(
					tk.getProcessInstanceId(), moduleName, StringUtils.defaultIfEmpty(variableName, "approve"),
					"1","",taskId);
			if (StringUtils.isNotBlank(roles)) {
				List<User> userList = processTraceManager.getUserList(roles, currentUser, null, tk.getProcessInstanceId());
				if (userList.size() == 1) {
					String uId = userList.get(0).getLoginName();
					processTraceManager.batchAgree(taskIds, uId, currentUser, variableName);
				}else if (userList.size() > 1){
					formatMessage.setMsg(roles);
				}else{
					formatMessage.setMsg("下一环节["+roles+"]角色中没有设置用户");
					formatMessage.setFlag(Messages.FAIL);
				}		
			} else {
				processTraceManager.batchAgree(taskIds, "", currentUser, variableName);
			}
		}
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 批量不同意单据
	 */
	@JsonOutput
	public String batchDisAgree() throws Exception {
		User currentUser = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		formatMessage.setMsg(null);
		if(StringUtils.isNotBlank(userIds)) { //存在选择用户情况下，直接同意即可
			processTraceManager.batchDisAgree(taskIds, userIds, currentUser, variableName);
		} else {
			taskId = taskIds[0];
			Task tk = processTraceManager.getTaskById(taskId);
			String pdk = tk.getProcessDefinitionId();
			moduleName = StringUtils.split(pdk, ":")[0];
			String roles = processTraceManager.getNextRoles(
					tk.getProcessInstanceId(), moduleName, StringUtils.defaultIfEmpty(variableName, "approve"),
					"0","",taskId);
			if (StringUtils.isNotBlank(roles)) {
				List<User> userList = processTraceManager.getUserList(roles, currentUser, null, tk.getProcessInstanceId());
				if (userList.size() == 1) {
					String uId = userList.get(0).getLoginName();
					processTraceManager.batchDisAgree(taskIds, uId, currentUser, variableName);
				}else if (userList.size() > 1){
					formatMessage.setMsg(roles);
				}else{
					formatMessage.setMsg("下一环节["+roles+"]角色中没有设置用户");
					formatMessage.setFlag(Messages.FAIL);
				}		
			} else {
				processTraceManager.batchDisAgree(taskIds, "", currentUser, variableName);
			}
		}
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 批量启动流程
	 */
	@JsonOutput
	public String batchStartProcessForSingleUser() throws Exception {
		User currentUser = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		formatMessage.setMsg(null);
		processTraceManager.batchStartProcessForSingleUser(ids, entityName, moduleName, currentUser);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 批量同意单据
	 */
	@JsonOutput
	public String batchAgreeForSingleUser() throws Exception {
		User currentUser = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		formatMessage.setMsg(null);
		processTraceManager.batchAgreeForSingleUser(taskIds, entityName, currentUser, "1", variableName);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 批量不同意单据
	 */
	@JsonOutput
	public String batchDisAgreeForSingleUser() throws Exception {
		User currentUser = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		formatMessage.setMsg(null);
		processTraceManager.batchAgreeForSingleUser(taskIds, entityName, currentUser, "0", variableName);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
	
	/**
	 * 保存数据并启动流程
	 * 
	 * @return
	 */
	@JsonOutput
	public String saveEntityAndStartProcess() {
		User currentUser = (User) Struts2Utils.getSessionAttribute(Constants.USER_SESSION_ID);
		String id = processTraceManager.saveEntityAndStartProcess(entityName, currentUser, jsonSaveData, jsonSenddata);
		formatMessage.setMsg(id);
		Struts2Utils.renderJson(formatMessage);
		return null;
	}
}